package n15_设计模式_交替运行输出;

import lombok.extern.slf4j.Slf4j;
import utils.Sleeper;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author fu
 * @date 2022-01-12 20:46
 * 概要：
 * ----------------------------------------------------------------
 * |                                                              |
 * |    [线程1] 输出a 5次； [线程2] 输出b 5次； [线程3] 输出c 5次； 现在要求输出 abcabcabcabcabc    |
 * |                                                            |
 * |=============================================================
 */
@Slf4j(topic = "c.T2")
public class T2_alternate_by_reentrantlock {

    public static void main(String[] args) {

        final AwaitSingal lock = new AwaitSingal(5);
        final Condition a = lock.newCondition();
        final Condition b = lock.newCondition();
        final Condition c = lock.newCondition();

        // 1. 首先 三个线程 各自进入 休息室
        new Thread(()->{
            lock.print("a", a, b);
        }, "t1").start();
        new Thread(()->{
            lock.print("b", b, c);
        }, "t2").start();
        new Thread(()->{
            lock.print("c", c, a);
        }, "t3").start();

        Sleeper.sleep(10);
        // 2. 主线程
        //   2.1 获得锁
        //   2.2 唤醒一个
        lock.lock();
        try {
            log.debug("主线程 发起 命令！");
            a.signal();
        } finally {
            lock.unlock();
        }
    }
}

@Slf4j(topic = "c.AwaitSingal")
class AwaitSingal extends ReentrantLock {

    private int loopNumber;

    public AwaitSingal(int loopNumber) {
        this.loopNumber = loopNumber;
    }

    public void print(String str, Condition currentWait, Condition nextSingal){

        for (int i = 0; i < loopNumber; i++) {
            lock();

            try {
                currentWait.await();
                log.debug(str);
                nextSingal.signal();

            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                unlock();
            }
        }
    }
}